<script setup>
import {ICONS} from "../const";
import {shallowRef} from "vue";
import {myInsert, myUpdate} from "../util";

/**
 * type: 表单类型，支持 insert 和 update 两种
 * data: 表单数据
 * rules: 表单规则
 * api: 表单提交的API函数
 * fn: 表单提交后的回调函数
 * width: 表单整体宽度（需要带单位）
 * items:
 *   通用:
 *     label: 文案，默认表单项属性名
 *     prop: 属性名
 *     required: 是否必填，默认 false
 *     disabled: 是否禁用，默认 false
 *     readonly: 是否只读，默认 false
 *     placeholder: 背景字，默认 "type + 表单属性名"
 *     span: 每个表单项的宽度占24分之多少，默认 24，表示独占一行
 *     hidden: 是否隐藏，默认 false，需要占位时改为 true
 *   number:
 *     min: 最小值，默认 0
 *     max: 最大值
 *     precision: 精度，默认 0
 *   textarea:
 *     rows: 行数，默认 8
 *     cols: 列数
 *   select:
 *     optionItems:
 *       label: 选项文案
 *       value: 值
 *   icon:
 *     iconSize: 按钮大小，默认 14
 *   cascader:
 *     options: 选项文案，格式为 [{value:1, label:'一级', children: [{value:11, label:'二级'}, {..}], {..}]
 *   date:
 *   password:
 *   其他:
 */
let parent = defineProps({
  'type': {type: String, required: false, default: 'insert'},
  'items': {type: Array, required: true},
  'data': {type: Object, required: true},
  'rules': {type: Object, required: true},
  'api': {type: Function, required: true},
  'fn': {type: Function, required: false},
  'width': {type: String, required: false, default: '100%'},
});

// 表单对象
let form = shallowRef();

// 添加数据: 发送请求 + 重置表单
async function insert() {
  await myInsert({
        'form': form,
        'api': parent['api'],
        'params': parent['data'],
        'fn': parent['fn']
      }
  );
  form.value.resetFields;
}

// 修改数据: 发送请求 + 重置表单
async function update() {
  await myUpdate({
    'form': form,
    'api': parent['api'],
    'params': parent['data'],
    'fn': parent['fn']
  });
  form.value.resetFields;
}

</script>

<template>

  <el-form class="my-form" ref="form" status-icon label-width="auto"
           :model="data" :rules="rules" :style="{'width': width}" size="small">

    <el-row :gutter="20">
      <el-col v-for="item in items" :key="item" :span="item['span'] || 24">
        <el-form-item :label="item['label'] || item['prop']" :prop="item['prop']"
                      :required="item['required']" v-show="!item['hidden']">
          <!--数字框-->
          <el-input-number v-if="item['type'] === 'number'" clearable
                           v-model="data[item['prop']]"
                           :min="item['min'] || 0" :max="item['max']"
                           :precision="item['precision'] || 0"
                           :placeholder="item['placeholder'] || ('type ' + item['prop'])"
                           :disabled="item['disabled']" :readonly="item['readonly']"/>

          <!--密码框-->
          <el-input v-else-if="item['type'] === 'password'" clearable show-password
                    v-model="data[item['prop']]"
                    :placeholder="item['placeholder'] || ('type ' + item['prop'])"
                    :disabled="item['disabled']" :readonly="item['readonly']"/>

          <!--文本域-->
          <el-input v-else-if="item['type'] === 'textarea'" type="textarea" clearable
                    v-model="data[item['prop']]" resize="none"
                    :rows="item['rows'] || 8" :cols="item['cols']"
                    :placeholder="item['placeholder'] || 'type ' + item['prop']"
                    :disabled="item['disabled']" :readonly="item['readonly']"/>

          <!--下拉框-->
          <el-select v-else-if="item['type'] === 'select'" clearable filterable
                     v-model="data[item['prop']]"
                     :placeholder="item['placeholder'] || 'type ' + item['prop']"
                     :disabled="item['disabled']" :readonly="item['readonly']">
            <el-option v-for="optionItem in item['optionItems']" :key="optionItem"
                       :label="optionItem['label']" :value="optionItem['value']"/>
          </el-select>

          <!--时间框-->
          <el-date-picker v-else-if="item['type'] === 'datetime'" type="datetime" clearable
                          v-model="data[item['prop']]"
                          format="YYYY-MM-DD HH:mm"
                          date-format="YYYY/MM/DD"
                          time-format="HH:mm"
                          value-format="YYYY-MM-DDTHH:mm:ss"
                          :placeholder="item['placeholder'] || 'type ' + item['prop']"
                          :disabled="item['disabled']" :readonly="item['readonly']"/>

          <!--日期时间框-->
          <el-date-picker v-else-if="item['type'] === 'date'" type="date" clearable
                          v-model="data[item['prop']]"
                          format="YYYY/MM/DD"
                          value-format="YYYY-MM-DD"
                          :placeholder="item['placeholder'] || 'type ' + item['prop']"
                          :disabled="item['disabled']" :readonly="item['readonly']"/>

          <!--时间框-->
          <el-time-picker v-else-if="item['type'] === 'time'"
                          v-model="data[item['prop']]"
                          format="HH:mm"
                          value-format="HH:mm:ss"
                          :placeholder="item['placeholder'] || 'type ' + item['prop']"
                          :disabled="item['disabled']" :readonly="item['readonly']"/>
<!--          <el-date-picker v-else-if="item['type'] === 'date'" type="date" clearable
                          v-model="data[item['prop']]"
                          format="YYYY/MM/DD"
                          value-format="YYYY-MM-DD"
                          :placeholder="item['placeholder'] || 'type ' + item['prop']"
                          :disabled="item['disabled']" :readonly="item['readonly']"/>-->

          <!--ICON单选框-->
          <el-radio-group v-else-if="item['type'] === 'icon'" class="icon-list"
                          v-model="data[item['prop']]" size="small">
            <el-radio-button v-for="icon in ICONS" :key="icon" :label="icon">
              <template #default>
                <el-icon :size="item['iconSize'] || 14">
                  <component :is="icon"/>
                </el-icon>
              </template>
            </el-radio-button>
          </el-radio-group>

          <!--级联框-->
          <el-cascader v-else-if="item['type'] === 'cascader'"
              v-model="data[item['prop']]"
              :options="item['options']"
              :props="{expandTrigger: 'hover'}"
              @change="data[item['fn']]" style="width: 100%;" />

          <!--文本框-->
          <el-input v-else clearable v-model="data[item['prop']]"
                    :placeholder="item['placeholder'] || 'type ' + item['prop']"
                    :disabled="item['disabled']" :readonly="item['readonly']"/>

        </el-form-item>
      </el-col>
    </el-row>

    <!--表单按钮项-->
    <el-form-item class="btn-item">
      <el-button v-if="type === 'insert'" type="primary" @click="insert">确认添加</el-button>
      <el-button v-else-if="type === 'update'" type="primary" @click="update">确认修改</el-button>
    </el-form-item>

  </el-form>
</template>

<style scoped lang="scss">
.my-form {
  .el-input-number, .el-button {
    width: 100%; // 宽度
  }
}

:deep(.el-date-editor) {
  --el-date-editor-width: 100%; // 宽度
}

.icon-list {

  margin-left: -2px; // 左外边距
  max-height: 160px; // 最大高度
  overflow-y: scroll; // Y滚动

  .el-radio-button {
    margin-bottom: 5px; // 下外边距
  }

}

/*取消首尾按钮的圆角*/
:deep(.el-radio-button:first-child .el-radio-button__inner),
:deep(.el-radio-button:last-child .el-radio-button__inner) {
  border-radius: 0; // 圆角
}

/*修改单选按钮样式*/
:deep(.el-radio-button--small .el-radio-button__inner) {
  border-left: 1px solid #7e7e7e; // 左边框
  margin: 0 2px; // 左右外边距
}
</style>